using System;
using MvcContrib.TestHelper;
using NUnit.Framework;
using Rhino.Mocks;
using SharpArch.Core.PersistenceSupport;
using System.Web.Mvc;
using gnodotnet.Core.MailingList;
using gnodotnet.Web.Controllers;
using gnodotnet.Web.Controllers.MailingList;
using SharpArch.Testing.NUnit;

namespace Tests.Specs.Recipients {
    public class AddingRecipientsSpec : GivenWhenThenTests {
        protected ActionResult _actionResult;
        protected RecipientsController _controller;
        protected IRepository<Recipient> _mockRepository;

        protected readonly Recipient _validRecipient = new Recipient { Name = "Test", Email = "test@test.com" };        
        public AddingRecipientsSpec() {
            given += () => {
                _mockRepository = MockRepository.GenerateMock<IRepository<Recipient>>();
                _controller = new RecipientsController(_mockRepository);
            };
        }
    }
    public class When_adding_a_new_recipient : AddingRecipientsSpec {
        public When_adding_a_new_recipient() {
            given += () => _mockRepository.Stub(r => r.FindOne(null)).IgnoreArguments().Return(null);
            when += () => _actionResult = _controller.Subscribe(_validRecipient);
        }
        [Test]
        public void will_redirect_back_to_the_home_page() {
            then = () => _actionResult.AssertActionRedirect().ToAction<HomeController>(c => c.Index());
        }
        [Test]
        public void will_persist_recipient() {
            then = () => _mockRepository.AssertWasCalled(r => r.SaveOrUpdate(_validRecipient));
        }
        [Test]
        public void will_pass_confirmation_message_to_the_view() {
            then = () => _controller.PageMessageContains("has been subscribed");
        }
    }
    public class When_updating_a_recipient_which_already_exists :AddingRecipientsSpec {
        public When_updating_a_recipient_which_already_exists() {
            given += () => _mockRepository.Stub(r => r.FindOne(null)).IgnoreArguments().Return(_validRecipient);
            when += () => _actionResult = _controller.Subscribe(_validRecipient);
        }
        [Test] public void will_not_persist_recipient() {
            then = () => _mockRepository.AssertWasNotCalled(r => r.SaveOrUpdate(Arg<Recipient>.Is.Anything));
        }   
        [Test] public void will_redirect_back_to_the_home_page() {
            then = () => _actionResult.AssertActionRedirect().ToAction<HomeController>(c => c.Index());
        }
        [Test]
        public void will_pass_error_message_to_the_view() {
            then = () => _controller.PageMessageContains("was previously subscribed");
        }
    }
    public static partial class TestExtensions {
        public static void PageMessageContains(this Controller controller, string partialMsg) {
            controller.TempData[ControllerEnums.GlobalViewDataProperty.PageMessage.ToString()].ToString()
                .ShouldContain(partialMsg);
            
        }
    }
}
